package controller

import (
	"config"
	"encoding/json"
	"fmt"
	"github.com/benbjohnson/phantomjs"
	"log"
	"model"
	"net/http"
	"net/url"
	"os"
	"spirit/mongodb"
	"spirit/utils"
	"spirit/utils/date"
	"spirit/utils/encrypt"
	"strconv"
	"strings"
	"time"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/tealeg/xlsx"
)

type InfoCollectionController struct {
	Data interface{}
}

type jsonBody struct {
	Url            string `json:"url"`
	ViewportWidth  int    `json:"viewport_width"`
	ViewportHeight int    `json:"viewport_height"`
	OutputFileName string `json:"output_file_name"`
	OutputFileExt  string `json:"output_file_ext"`
	Quility        int    `json:"quility"`
	OutputUri      string `json:"output_uri"`
}

var (
	se  = encrypt.SimpleEncrypt{Key: "topnet2015topnet2015"}
	se2 = &encrypt.SimpleEncrypt{Key: "2017jianyu"}
)

const OutputDir = "screen_shot"

func sessionVerify() gin.HandlerFunc {
	return func(c *gin.Context) {
		session := sessions.Default(c)
		account := session.Get("account")
		role := session.Get("role")
		if account == nil || role == nil {
			c.Abort()
			c.HTML(http.StatusOK, "login.html", gin.H{"code": -1, "msg": "登录超时请重新登录"})
			return
		}
	}
}

func (ctrl *InfoCollectionController) Router(router *gin.Engine) {
	infoCollectionGroup := router.Group("/infoCollection")
	//导出报告
	infoCollectionGroup.GET("/toExport/*id", infoCollectionExport)
	infoCollectionGroup.Use(sessionVerify())
	{
		infoCollectionGroup.GET("", infoCollection)
		infoCollectionGroup.POST("/addUser", infoCollectionAddUser)
		infoCollectionGroup.POST("/delUser", infoCollectionDelUser)
		infoCollectionGroup.GET("/add/*id", infoCollectionAdd)
		infoCollectionGroup.POST("/list", infoCollectionList)

		infoCollectionGroup.GET("/history", infoCollectionHistory) //历史记录
		infoCollectionGroup.GET("/toHistory", toHistory)
		infoCollectionGroup.POST("/historyList", infoCollectionListForHistory)
		infoCollectionGroup.POST("/getById", infoCollectionGetById)
		infoCollectionGroup.POST("/save", save)
		infoCollectionGroup.POST("/exportData", exportData)
		//打印报告
		infoCollectionGroup.GET("/toReport/*id", infoCollectionReport)

		//保存报告
		infoCollectionGroup.GET("/toSaveReport/*id", toSaveReport)

		//获取所有反馈信息
		infoCollectionGroup.POST("/getAllFeedbacks", getAllFeedbacks)
		infoCollectionGroup.POST("/saveFeedbackCont", saveFeedbackCont)
	}

}

func phantomjs_screen_shot(config *jsonBody) {
	uri := fmt.Sprintf("%s/%s", OutputDir, config.OutputFileName)
	config.OutputFileName = uri
	config.OutputUri = uri
	// Start the process once.
	if err := phantomjs.DefaultProcess.Open(); err != nil {
		panic(err)
		os.Exit(1)
	}
	defer phantomjs.DefaultProcess.Close()

	page, err := phantomjs.CreateWebPage()
	if err != nil {
		panic(err)
	}
	//set request headers
	requestHeader := http.Header{
		"User-Agent": []string{"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"},
	}

	if err := page.SetCustomHeaders(requestHeader); err != nil {
		panic(err)
	}

	// Setup the viewport and render the results view.
	if err := page.SetViewportSize(config.ViewportWidth, config.ViewportHeight); err != nil {
		panic(err)
	}
	// Open a URL.
	log.Println("渲染url:", config.Url)
	if err := page.Open("http://localhost:8081" + config.Url); err != nil {
		panic(err)
	}
	if err := page.Render(config.OutputFileName, config.OutputFileExt, config.Quility); err != nil {
		panic(err)
	}
}

/**
保存报告方法action
*/
func toSaveReport(context *gin.Context) {
	session := sessions.Default(context)
	organCode := session.Get("organCode").(string)

	area := session.Get("area").(string)
	role := session.Get("role").(string)

	originUrl := context.Request.URL.String()
	encodeId := ""
	if strings.LastIndex(originUrl, "?") > -1 {
		encodeId = originUrl[len("/infoCollection/toSaveReport/"):strings.LastIndex(originUrl, "?")]
	} else {
		encodeId = originUrl[len("/infoCollection/toSaveReport/"):len(originUrl)]
	}
	log.Println("encodeId:", encodeId)
	id := decodeId(encodeId)
	postParameters := jsonBody{Url: "/infoCollection/toExport/" + encodeId + "?area=" + area + "&organCode=" + organCode + "&role=" + role, ViewportHeight: 2480, ViewportWidth: 960, OutputFileName: id + ".png", OutputFileExt: "png", Quility: 50, OutputUri: OutputDir}
	//截图网页
	phantomjs_screen_shot(&postParameters)
}

/**
phantomjs 生成图片url对应的action 页面渲染数据
*/
func infoCollectionExport(ctx *gin.Context) {
	area := ctx.Query("area")
	organCode := ctx.Query("organCode")
	role := ctx.Query("role")
	year := ctx.Query("year")
	screenDate := date.FormatYYYYMMDD(time.Now())
	m := gin.H{"area": area, "screenOrganCode": organCode, "organs": config.Organs, "screenDate": screenDate, "role": role, "currentYear": config.CurrentYear}
	originUrl := ctx.Request.URL.String()
	//encodeId := originUrl[len("/infoCollection/toReport/"):len(originUrl)]
	encodeId := ""
	if strings.LastIndex(originUrl, "?") > -1 {
		encodeId = originUrl[len("/infoCollection/toExport/"):strings.LastIndex(originUrl, "?")]
	} else {
		encodeId = originUrl[len("/infoCollection/toExport/"):len(originUrl)]
	}
	tbName := ""
	if year != "" {
		tbName = "infoCollection_" + year
		m["year"] = year
	} else {
		tbName = config.TbBaseName
	}
	id := decodeId(encodeId)
	personInfo := mongodb.FindById(tbName, id, nil)
	m["baseInfo"] = (*personInfo)["baseInfo"]
	m["createOrganName"] = (*personInfo)["createOrganName"]
	m["physicalCheckup"] = (*personInfo)["physicalCheckup"]
	physicalCheckup := (*personInfo)["physicalCheckup"] //体格检查
	_physicalCheckup := make(map[string]interface{}, 0)

	pastMedicalHistory := (*personInfo)["pastMedicalHistory"] //既往病史
	_pastMedicalHistory := make(map[string]interface{}, 0)
	if pastMedicalHistory != nil {
		_pastMedicalHistory = pastMedicalHistory.(map[string]interface{})
	}
	if physicalCheckup != nil {
		_physicalCheckup = physicalCheckup.(map[string]interface{})
		m["BMI"] = displayBMI(_physicalCheckup["tigejiancha_bmi"].(string), 18.5, 23.9)
		firstSBP, firstDSP, gxyResult := displaySBPAndDSP(_physicalCheckup, _pastMedicalHistory)
		m["firstSBP"] = firstSBP
		m["firstDSP"] = firstDSP
		m["gxyResult"] = gxyResult

		tigejiancha_bmi := _physicalCheckup["tigejiancha_bmi"].(string)
		_tigejiancha_bmi, _ := strconv.ParseFloat(tigejiancha_bmi, 64)
		BMI_result := "" //最后动态建议部分BMI内容
		if _tigejiancha_bmi > 28 {
			BMI_result = reportMap["BMI"]["1"]
			//if shengao:= _physicalCheckup["tigejiancha_height"];shengao!=nil{
			//	_shengao:=shengao.
			//}
			////console.log("身高:",shengao,"建议体重:",toDecimal(shengao * 23.9));
			//BMI_result = BMI_result.replace(/TZ/, toDecimal(shengao * shengao * 23.9))
			//$("#BMI_").html(BMI_result)
			//$("#BMI").show()
		}
		m["BMI_result"] = BMI_result
	}

	ctx.HTML(http.StatusOK, "infoCollection/export.html", m)
}

/*历史记录*/
func infoCollectionHistory(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "infoCollection/history.html", gin.H{"screenYearRecord": config.ScreenYearRecord})
}

func toHistory(ctx *gin.Context) {
	session := sessions.Default(ctx)
	organName := session.Get("organName")
	area := session.Get("area")
	role := session.Get("role")
	organs := config.Organs
	year := ctx.Request.FormValue("year")
	ctx.HTML(http.StatusOK, "infoCollection/historyList.html", gin.H{"organName": organName, "area": area, "organs": organs, "role": role, "year": year})
}

func infoCollectionListForHistory(ctx *gin.Context) {
	year := ctx.Request.FormValue("year")
	data := make([]map[string]interface{}, 0)
	result := &model.BaseResult{}
	result.Data = data
	idCard := ctx.Request.FormValue("idCard")
	phone := ctx.Request.FormValue("phone")
	userName := ctx.Request.FormValue("userName")
	page := ctx.Request.FormValue("page")
	pageSize := ctx.Request.FormValue("pageSize")

	organCode := GetSessionInfo("organCode", ctx)
	role := GetSessionInfo("role", ctx)
	_page, _ := strconv.Atoi(page)
	_pageSize, _ := strconv.Atoi(pageSize)
	start := (_page - 1) * _pageSize
	query := make(map[string]interface{}, 0)
	tbName := "infoCollection_" + year
	if role == "2" {
		tbName = "infoCollection2_" + year
	}

	if role == "0" {
		if organCode != "" && organCode != nil {
			query["createOrganCode"] = organCode
		}
	}

	if userName != "" {
		query["baseInfo.userName"] = userName
	}
	if idCard != "" {
		query["baseInfo.idCard"] = idCard
	}
	if phone != "" {
		query["baseInfo.phone"] = phone
	}

	area := ctx.Request.FormValue("area")
	organ := ctx.Request.FormValue("organ")
	if organ == "" && area != "" {
		query["area"] = area
	} else if area == "" && organ != "" {
		query["createOrganCode"] = organ
	}
	fengxiandengji := ctx.Request.FormValue("fengxiandengji")
	if fengxiandengji != "" {
		query["ccRiskRating.risk_level"] = fengxiandengji
	}

	m := mongodb.Find(tbName, query, `{"_id":-1}`, nil, false, start, _pageSize)
	totalCount := mongodb.Count(tbName, query)
	//__tmp := totalCount / _pageSize
	//totalPage := math.Ceil(float64(__tmp))
	totalPage := (totalCount + _pageSize - 1) / _pageSize
	if len(*m) > 0 {
		for _, val := range *m {
			id := utils.BsonIdToSId(val["_id"])
			a := se.EncodeStringByCheck(id)
			val["_id"] = url.QueryEscape("ABC" + se2.EncodeStringByCheck(a))
		}
	}
	result.Data = map[string]interface{}{
		"rows":       m,
		"totalCount": totalCount,
		"totalPage":  totalPage,
	}
	ctx.JSON(http.StatusOK, result)
}

//
func infoCollectionReport(ctx *gin.Context) {
	session := sessions.Default(ctx)
	organCode := session.Get("organCode")
	area := session.Get("area")
	role := session.Get("role")
	screenDate := date.FormatYYYYMMDD(time.Now())
	originUrl := ctx.Request.URL.String()
	//encodeId := originUrl[len("/infoCollection/toReport/"):len(originUrl)]
	encodeId := ""
	if strings.LastIndex(originUrl, "?") > -1 {
		encodeId = originUrl[len("/infoCollection/toReport/"):strings.LastIndex(originUrl, "?")]
	} else {
		encodeId = originUrl[len("/infoCollection/toReport/"):len(originUrl)]
	}
	//encodeId := ctx.Param("id")
	log.Println("encodeId:", encodeId)
	//id := decodeId(encodeId)
	m := gin.H{"area": area, "screenOrganCode": organCode, "organs": config.Organs, "screenDate": screenDate, "role": role, "currentYear": config.CurrentYear}
	year := ctx.Request.FormValue("y")
	if year != "" {
		m["year"] = year
		if year != config.CurrentYear {
			m["canUpdate"] = false
		}
	}
	if encodeId != "" {
		m["screenId"] = encodeId
	}
	ctx.HTML(http.StatusOK, "infoCollection/report.html", m)
}

//
func saveFeedbackCont(ctx *gin.Context) {
	result := &model.BaseResult{}
	data := ctx.Request.FormValue("data")
	_m := map[string]interface{}{}
	json.Unmarshal([]byte(data), &_m)
	var _guidePhysician = utils.ObjToString(_m["_guidePhysician"])
	var _replyContent = utils.ObjToString(_m["_replyContent"])
	var _replyTime = utils.ObjToString(_m["_replyTime"])
	var _feedbackId = utils.ObjToString(_m["_feedbackId"])
	var _userName = utils.ObjToString(_m["_userName"])
	var _feedC = utils.ObjToString(_m["_feedC"])
	var _feedTime = utils.ObjToString(_m["_feedTime"])
	formatTime, _ := time.Parse("2006-01-02", _replyTime)
	if _guidePhysician != "" && _replyContent != "" && _replyTime != "" {
		tbName := "feedback"
		if _feedbackId != "" {
			res := mongodb.FindById(tbName, _feedbackId, nil)
			if len(*res) > 0 {
				(*res)["replyTime"] = formatTime.Unix()
				(*res)["status"] = 1
				(*res)["guidePhysician"] = _guidePhysician
				(*res)["replyContent"] = _replyContent
				b := mongodb.UpdateById(tbName, _feedbackId, *res)
				if b {
					result.Code = 1
				}
			}
		} else {
			query := make(map[string]interface{}, 0)
			query["replyContent"] = _replyContent
			query["guidePhysician"] = _guidePhysician
			log.Println(formatTime.Unix())
			query["replyTime"] = formatTime.Unix()
			query["status"] = 1 //未回复:0 已回复:1
			query["style"] = "F"
			query["userName"] = _userName
			query["feedTime"] = _feedTime //应该为空
			query["textarea"] = _feedC    //应该为空
			query["phone"] = utils.ObjToString(_m["_phone"])
			query["idCard"] = utils.ObjToString(_m["_idCard"])
			query["createTime"] = time.Now().Unix()
			id := mongodb.Save(tbName, query)
			if id != "" {
				result.Code = 1
			}
		}
	}
	ctx.JSON(http.StatusOK, result)
}

//
func getAllFeedbacks(ctx *gin.Context) {
	result := &model.BaseResult{}
	tbName := "feedback"
	idCard := ctx.Request.FormValue("idCard")
	pageNum, _ := strconv.Atoi(ctx.Request.FormValue("pageNum"))
	pageLimit, _ := strconv.Atoi(ctx.Request.FormValue("pageLimit"))
	pstart := (pageNum - 1) * pageLimit
	if idCard != "" && pageNum > 0 {
		query := map[string]interface{}{
			"idCard": idCard,
		}
		count := mongodb.Count(tbName, query)
		res := mongodb.Find(tbName, query, `{"createTime":1}`, nil, false, pstart, pageLimit)
		if len(*res) > 0 {
			for _, v := range *res {
				creatTime := v["createTime"]
				v["createTime"] = date.FormatDateWithObj(&creatTime, date.Date_Short_Layout)
				if v["replyTime"] != nil {
					replyTime := v["replyTime"]
					v["replyTime"] = date.FormatDateWithObj(&replyTime, date.Date_Short_Layout)
				}
				if v["feedTime"] != nil {
					replyTime := v["feedTime"]
					v["feedTime"] = date.FormatDateWithObj(&replyTime, date.Date_Short_Layout)
				}
			}
			result.Data = *res
			result.Code = count
		} else {
			result.Code = 0
		}
	} else {
		result.Code = 0
	}
	ctx.JSON(http.StatusOK, result)

}

//
func infoCollectionAddUser(ctx *gin.Context) {
	result := &model.BaseResult{}
	role := GetSessionInfo("role", ctx)
	tbName := config.TbBaseName
	if role == "2" {
		tbName = config.TbBaseName2
	}
	userName := ctx.Request.FormValue("userName")
	idCard := ctx.Request.FormValue("idCard")
	if userName != "" && idCard != "" {
		if _, ok := config.IdCardCaches.Load(idCard); ok {
			result.Code = -1
			result.Msg = "已经存在该用户【" + idCard + "】的筛查信息不要重复添加"
		} else {
			query := map[string]interface{}{
				"baseInfo.idCard": idCard,
			}
			tmp := mongodb.FindOne(tbName, query)
			if tmp != nil && len(*tmp) > 0 {
				result.Code = -1
				result.Msg = "已经存在该用户【" + idCard + "】的筛查信息不要重复添加"
			} else {
				m := &map[string]interface{}{}
				organCode := GetSessionInfo("organCode", ctx)
				organName := GetSessionInfo("organName", ctx)
				area := GetSessionInfo("area", ctx)
				account := GetSessionInfo("account", ctx)
				(*m)["createUser"] = account
				(*m)["createOrganCode"] = organCode
				(*m)["createOrganName"] = organName
				(*m)["area"] = area
				(*m)["createTime"] = time.Now().Unix()
				baseInfo := map[string]interface{}{
					"userName": userName,
					"idCard":   idCard,
				}
				(*m)["baseInfo"] = baseInfo
				id := mongodb.Save(tbName, m)
				if id != "" {
					result.Code = 0
					result.Msg = "保存成功"
					result.Data = map[string]string{"id": id}
				} else {
					result.Code = 1
					result.Msg = "保存未成功,请稍后重试"
				}
			}
		}

	}

	ctx.JSON(http.StatusOK, result)
}

//删除信息
func infoCollectionDelUser(ctx *gin.Context) {
	result := &model.BaseResult{}
	role := GetSessionInfo("role", ctx)
	encodeId := ctx.Request.FormValue("id")
	year := ctx.Request.FormValue("year")
	tbName := ""
	if year != "" {
		tbName = "infoCollection_" + year
		if role == "2" {
			tbName = "infoCollection2_" + year
		}
	} else {
		tbName = config.TbBaseName
		if role == "2" {
			tbName = config.TbBaseName2
		}
	}
	if encodeId != "" {
		id := decodeId(encodeId)
		b := mongodb.DelById(tbName, id)
		if b {
			result.Code = 0
			result.Msg = "删除成功!"
		} else {
			result.Code = -1
			result.Msg = "信息删除失败请稍后重试!"
		}
	}
	ctx.JSON(http.StatusOK, result)
}

func infoCollectionAdd(ctx *gin.Context) {
	session := sessions.Default(ctx)
	organCode := session.Get("organCode")
	area := session.Get("area")
	role := session.Get("role")
	screenDate := date.FormatYYYYMMDD(time.Now())
	originUrl := ctx.Request.URL.String()
	encodeId := ""
	if strings.LastIndex(originUrl, "?") > -1 {
		encodeId = originUrl[len("/infoCollection/add/"):strings.LastIndex(originUrl, "?")]
	} else {
		encodeId = originUrl[len("/infoCollection/add/"):len(originUrl)]
	}
	//encodeId := ctx.Param("id")
	//log.Println("encodeId:", encodeId)
	//id := decodeId(encodeId)

	m := gin.H{"area": area, "screenOrganCode": organCode, "organs": config.Organs, "screenDate": screenDate, "role": role, "currentYear": config.CurrentYear}

	year := ctx.Request.FormValue("y")
	if year != "" {
		m["year"] = year
		if year != config.CurrentYear {
			m["canUpdate"] = false
		}
	}
	if encodeId != "" {
		m["screenId"] = encodeId
	}

	ctx.HTML(http.StatusOK, "infoCollection/add.html", m)
}

func decodeId(id string) string {
	if !strings.Contains(id, "+") { //新加密算法解密
		id, _ = url.QueryUnescape(id)
	}
	kstr := se2.DecodeStringByCheck(id[3:])
	return strings.Split(se.DecodeStringByCheck(kstr), ",")[0]
}
func infoCollection(ctx *gin.Context) {
	session := sessions.Default(ctx)
	organName := session.Get("organName")
	area := session.Get("area")
	role := session.Get("role")
	organs := config.Organs
	ctx.HTML(http.StatusOK, "infoCollection/list.html", gin.H{"organName": organName, "area": area, "organs": organs, "role": role, "currentYear": config.CurrentYear})
}
func infoCollectionGetById(ctx *gin.Context) {
	role := GetSessionInfo("role", ctx)
	year := ctx.Request.FormValue("year")
	tbName := ""
	if year != "" {
		tbName = "infoCollection_" + year
		if role == "2" {
			tbName = "infoCollection2_" + year
		}
	} else {
		tbName = config.TbBaseName
		if role == "2" {
			tbName = config.TbBaseName2
		}
	}

	encodeId := ctx.Request.FormValue("id")
	id := decodeId(encodeId)
	m := mongodb.FindById(tbName, id, nil)
	result := &model.BaseResult{}
	result.Data = m
	result.Msg = ""
	result.Code = 0
	ctx.JSON(http.StatusOK, result)
}

func infoCollectionList(ctx *gin.Context) {
	data := make([]map[string]interface{}, 0)
	result := &model.BaseResult{}
	result.Data = data
	idCard := ctx.Request.FormValue("idCard")
	phone := ctx.Request.FormValue("phone")
	userName := ctx.Request.FormValue("userName")
	page := ctx.Request.FormValue("page")
	pageSize := ctx.Request.FormValue("pageSize")

	multiQuery := false //是否是详细查询个人筛查数据
	if idCard != "" || phone != "" || userName != "" {
		multiQuery = true
	}

	createUser := GetSessionInfo("account", ctx)
	role := GetSessionInfo("role", ctx)
	_page, _ := strconv.Atoi(page)
	_pageSize, _ := strconv.Atoi(pageSize)
	start := (_page - 1) * _pageSize
	query := make(map[string]interface{}, 0)
	if userName != "" {
		query["baseInfo.userName"] = userName
	}
	if idCard != "" {
		query["baseInfo.idCard"] = idCard
	}
	if phone != "" {
		query["baseInfo.phone"] = phone
	}
	if role == "0" {
		if createUser != "" && createUser != nil {
			query["createUser"] = createUser
		}
	} else if role == "1" || role == "2" {
		fengxiandengji := ctx.Request.FormValue("fengxiandengji")
		area := ctx.Request.FormValue("area")
		organ := ctx.Request.FormValue("organ")
		if organ == "" && area != "" {
			query["area"] = area
		} else if area == "" && organ != "" {
			query["createOrganCode"] = organ
		}
		if fengxiandengji != "" {
			query["ccRiskRating.risk_level"] = fengxiandengji
		}

	}

	queryTbNames := make([]string, 0)
	queryTbNames = append(queryTbNames, config.CurrentYear)
	if multiQuery {
		for _, year := range config.ScreenYearRecord {
			queryTbNames = append(queryTbNames, year)
		}
	}

	var totalCount int
	for _, year := range queryTbNames {
		tb := "infoCollection_" + year
		if role == "2" {
			tb = "infoCollection2_" + year
		}
		count := mongodb.Count(tb, query)
		if count > 0 {
			m := mongodb.Find(tb, query, `{"_id":-1}`, nil, false, start, _pageSize)
			//查询出来的结果附带上数据所在的年份,方便前台传参,从而到指定的year表查询详情
			for _, d := range *m {
				d["tbYear"] = year
			}
			data = append(data, *m...)
			totalCount += count
		}
	}

	//m := mongodb.Find(tbName, query, `{"_id":-1}`, nil, false, start, _pageSize)
	//totalCount := mongodb.Count(tbName, query)
	totalPage := (totalCount + _pageSize - 1) / _pageSize
	if len(data) > 0 {
		for _, val := range data {
			id := utils.BsonIdToSId(val["_id"])
			a := se.EncodeStringByCheck(id)
			val["_id"] = url.QueryEscape("ABC" + se2.EncodeStringByCheck(a))
		}
	}
	result.Data = map[string]interface{}{
		"rows":       data,
		"totalCount": totalCount,
		"totalPage":  totalPage,
	}
	ctx.JSON(http.StatusOK, result)
}
func save(ctx *gin.Context) {
	var (
		err error
	)
	result := &model.BaseResult{}
	_type := ctx.Request.FormValue("type")
	id := ctx.Request.FormValue("id")
	data := ctx.Request.FormValue("data")
	m := &map[string]interface{}{}

	_m := map[string]interface{}{}
	err = json.Unmarshal([]byte(data), &_m)
	organCode := GetSessionInfo("organCode", ctx)
	organName := GetSessionInfo("organName", ctx)
	area := GetSessionInfo("area", ctx)
	account := GetSessionInfo("account", ctx)
	role := GetSessionInfo("role", ctx)
	tbName := config.TbBaseName
	if role == "2" {
		tbName = config.TbBaseName2
	}
	if err != nil {
		result.Code = 1
		result.Msg = "提交数据存在异常,请稍后重试"
		log.Printf("保存数据反序列化出错,error:[%v],type:[%s],data:[%s]", err, _type, data)
	} else {
		if id == "" {
			(*m)["createUser"] = account
			(*m)["createOrganCode"] = organCode
			(*m)["createOrganName"] = organName
			(*m)["area"] = area
			(*m)["createTime"] = time.Now().Unix()
			(*m)[_type] = _m
			log.Printf("保存数据,type:[%s],data:[%s]", _type, data)

			id := mongodb.Save(tbName, m)
			if id != "" {
				result.Code = 0
				result.Msg = "保存成功"
				result.Data = map[string]string{"id": id}
			} else {
				result.Code = 1
				result.Msg = "保存未成功,请稍后重试"
			}
		} else {
			//log.Printf("更新数据,id:[%s],type:[%s],data:[%s]", id, _type, data)
			log.Printf("更新数据,id:[%s],type:[%s]", id, _type)
			_id := decodeId(id)
			m = mongodb.FindById(tbName, _id, nil)

			//----------------------------------------
			var _ccRiskRating map[string]interface{}
			ccRiskRating := (*m)["ccRiskRating"]
			if ccRiskRating != nil {
				_ccRiskRating = ccRiskRating.(map[string]interface{})
			} else {
				_ccRiskRating = make(map[string]interface{}, 0)
			}
			//----------------------------------------

			if _type == "livingStatus" {
				if _m["smokingStatus"] == "正在吸" {
					_m["smokingYearsForGiveUp"] = ""
					_m["smokingYearsForHistory"] = ""
				} else if _m["smokingStatus"] == "已戒烟" {
					_m["smokingYearsForNow"] = ""
					_m["smokingAmountForNow"] = ""
				}
				if _m["isSmoking"] == "是" {
					log.Printf("有吸烟史,设置ccRiskRating")
					_ccRiskRating["fengxianpingji_xiyan"] = "有"
					log.Printf("_ccRiskRating['fengxianpingji_xiyan']设置[有]成功......")
				} else {
					_ccRiskRating["fengxianpingji_xiyan"] = "无"
				}
				if _m["sportStatus"] == "缺乏运动" {
					log.Printf("运动缺乏,设置ccRiskRating")
					_ccRiskRating["fengxianpingji_yundong"] = "是"
					log.Printf("_ccRiskRating['fengxianpingji_yundong']设置[是]成功......")
				} else {
					_ccRiskRating["fengxianpingji_yundong"] = "否"
				}
			}
			if _type == "family" {
				if _m["jiazushi_zhongfeng"] == "有" {
					log.Printf("有脑卒中家族史,设置ccRiskRating")
					_ccRiskRating["fengxianpingji_naocuzhong_family_history"] = "有"
					log.Printf("_ccRiskRating['fengxianpingji_naocuzhong_family_history']设置[有]成功......")
				} else {
					_ccRiskRating["fengxianpingji_naocuzhong_family_history"] = "无"
				}
			}
			if _type == "pastMedicalHistory" {
				//处理既往病史时候 需要查看体格检查和实验室检查,用以同时确定高血压、血脂、糖尿病
				physicalCheckup := (*m)["physicalCheckup"]
				labExamination := (*m)["labExamination"]
				var _physicalCheckup, _labExamination map[string]interface{}
				if physicalCheckup != nil {
					_physicalCheckup = physicalCheckup.(map[string]interface{})
				} else {
					_physicalCheckup = make(map[string]interface{}, 0)
				}
				if labExamination != nil {
					_labExamination = labExamination.(map[string]interface{})
				} else {
					_labExamination = make(map[string]interface{}, 0)
				}
				dealPastMedicalHistoryUpdateData(_m, _physicalCheckup, _labExamination, _ccRiskRating)
			}

			//处理体格检查和实验室检查 同时也要查看既往病史
			pastMedicalHistory := (*m)["pastMedicalHistory"]
			var _pastMedicalHistory map[string]interface{}
			if pastMedicalHistory != nil {
				_pastMedicalHistory = pastMedicalHistory.(map[string]interface{})
			} else {
				_pastMedicalHistory = make(map[string]interface{}, 0)
			}
			if _type == "physicalCheckup" {
				//体格检查
				if _m["tigejiancha_bmi"] != nil {
					_bmi, _ := strconv.ParseFloat(_m["tigejiancha_bmi"].(string), 64)
					if _bmi >= 28.0 {
						log.Printf("超重,设置ccRiskRating")
						_ccRiskRating["fengxianpingji_chaozhong"] = "是"
						log.Printf("_ccRiskRating['fengxianpingji_chaozhong']设置[是]成功......")
					} else {
						_ccRiskRating["fengxianpingji_chaozhong"] = "否"
					}
				}
				var (
					firstSBP, firstDSP, secondSBP, secondDSP int
					gaoxueya                                 string
				)
				if _m["tigejiancha_xueya_firstSBP"] != nil {
					firstSBP, _ = strconv.Atoi(_m["tigejiancha_xueya_firstSBP"].(string))
				}
				if _m["tigejiancha_xueya_firstDSP"] != nil {
					firstDSP, _ = strconv.Atoi(_m["tigejiancha_xueya_firstDSP"].(string))
				}

				if _m["tigejiancha_xueya_secondSBP"] != nil {
					secondSBP, _ = strconv.Atoi(_m["tigejiancha_xueya_secondSBP"].(string))
				}
				if _m["tigejiancha_xueya_secondDSP"] != nil {
					secondDSP, _ = strconv.Atoi(_m["tigejiancha_xueya_secondDSP"].(string))
				}
				if _pastMedicalHistory["gaoxueya"] != nil {
					gaoxueya = _pastMedicalHistory["gaoxueya"].(string)
				}

				if firstSBP >= 140 || secondSBP >= 140 || firstDSP >= 90 || secondDSP >= 90 || gaoxueya == "有" {
					_ccRiskRating["fengxianpingji_gaoxueya"] = "有"
				} else {
					_ccRiskRating["fengxianpingji_gaoxueya"] = "无"
				}
			}
			if _type == "labExamination" {
				//实验室检查
				var (
					xuetang_kongfu, xuetang_canhou                        float64
					xuezhi_ganyousanzhi, xuezhi_danguchun, xuezhi_gaomidu float64
					xzyc, tnb                                             string
				)
				if _m["xuetang_kongfu"] != nil {
					xuetang_kongfu, _ = strconv.ParseFloat(_m["xuetang_kongfu"].(string), 64)
				}
				if _m["xuetang_canhou"] != nil {
					xuetang_canhou, _ = strconv.ParseFloat(_m["xuetang_canhou"].(string), 64)
				}

				if _pastMedicalHistory["tnb"] != nil {
					tnb = _pastMedicalHistory["tnb"].(string)
				}
				if xuetang_kongfu >= 7.0 || xuetang_canhou >= 11.0 || tnb == "有" {
					_ccRiskRating["fengxianpingji_tnb"] = "有"
				} else {
					_ccRiskRating["fengxianpingji_tnb"] = "无"
				}

				//----------------------
				if _m["xuezhi_ganyousanzhi"] != nil {
					xuezhi_ganyousanzhi, _ = strconv.ParseFloat(_m["xuezhi_ganyousanzhi"].(string), 64)
				}
				if _m["xuezhi_danguchun"] != nil {
					xuezhi_danguchun, _ = strconv.ParseFloat(_m["xuezhi_danguchun"].(string), 64)
				}
				if _m["xuezhi_gaomidu"] != nil {
					xuezhi_gaomidu, _ = strconv.ParseFloat(_m["xuezhi_gaomidu"].(string), 64)
				}
				if _pastMedicalHistory["xzyc"] != nil {
					xzyc = _pastMedicalHistory["xzyc"].(string)
				}
				if xuezhi_danguchun >= 6.22 || xuezhi_ganyousanzhi >= 2.26 || xuezhi_gaomidu < 1.04 || xzyc == "有" {
					_ccRiskRating["fengxianpingji_xzyc"] = "是"
				} else {
					_ccRiskRating["fengxianpingji_xzyc"] = "否"
				}

			}
			(*m)[_type] = _m
			(*m)["updateTime"] = time.Now().Unix()
			ccRiskRatingDeal(_ccRiskRating)
			(*m)["ccRiskRating"] = _ccRiskRating
			b := mongodb.UpdateById(tbName, _id, *m)
			if b {
				result.Code = 0
				result.Msg = "更新成功"
				result.Data = map[string]string{"id": id}
			} else {
				result.Code = 1
				result.Msg = "更新未成功,请稍后重试"
			}
		}
	}

	ctx.JSON(http.StatusOK, result)
}

func ccRiskRatingDeal(ccRiskRatingData map[string]interface{}) {
	var risk_number = 0
	for key, val := range ccRiskRatingData {
		if (key != "fengxianpingji_naocuzhong_history" && key != "fengxianpingji_TIA_history") && (val == "有" || val == "是") {
			risk_number++
		}
	}
	if ccRiskRatingData["fengxianpingji_naocuzhong_history"] == "有" || ccRiskRatingData["fengxianpingji_TIA_history"] == "有" {
		ccRiskRatingData["risk_level"] = "高危"
		ccRiskRatingData["risk_reason"] = "有脑卒中或者TIA"
	} else if risk_number >= 3 {
		ccRiskRatingData["risk_level"] = "高危"
		ccRiskRatingData["risk_reason"] = "患有除脑卒中和TIA之外的其他危险因素项目数量大于等于3"
	} else if risk_number < 3 {
		if ccRiskRatingData["fengxianpingji_gaoxueya"] == "有" || ccRiskRatingData["fengxianpingji_tnb"] == "有" || ccRiskRatingData["fengxianpingji_fc"] == "有" {
			ccRiskRatingData["risk_level"] = "中危"
			ccRiskRatingData["risk_reason"] = "有高血压、糖尿病、房颤或者瓣膜性心脏病三种慢性病之一"
		} else {
			ccRiskRatingData["risk_level"] = "低危"
			ccRiskRatingData["risk_reason"] = "具有三项以下危险因素且无高血压、糖尿病、心房颤动或者瓣膜性心脏病等慢性疾病"
		}
	}
}

func exportData(ctx *gin.Context) {
	role := GetSessionInfo("role", ctx)
	year := ctx.Request.FormValue("year")
	tbName := ""
	if year == "" {
		year = config.CurrentYear
	}
	tbName = "infoCollection_" + year
	if role == "2" {
		tbName = "infoCollection2_" + year
	}
	queryParam := ctx.Request.FormValue("queryParam")
	//log.Println("数据导出queryParam:", queryParam)
	queryMap := map[string]interface{}{}
	if queryParam != "" {
		err := json.Unmarshal([]byte(queryParam), &queryMap)
		if err == nil {
			log.Println("数据导出queryParam:", queryMap)
			data := mongodb.Find(tbName, queryMap, `{"_id":-1}`, nil, false, 0, 50000)
			dataLen := len(*data)
			if dataLen > 0 && dataLen < 15000 {
				fileName := ""
				if queryMap["area"] != "" && queryMap["area"] != nil {
					fileName = getAreaNameByCode(queryMap["area"].(string))
				} else if queryMap["createOrganCode"] != "" && queryMap["createOrganCode"] != nil {
					fileName = getAreaNameByCode(queryMap["createOrganCode"].(string))
				}
				file := xlsx.NewFile()
				sheet, _ := file.AddSheet("Sheet1")
				var row *xlsx.Row
				var cell *xlsx.Cell
				//边框
				border := xlsx.Border{
					Left:        "thin",
					LeftColor:   "00A6A6A6",
					Right:       "thin",
					RightColor:  "00A6A6A6",
					Top:         "thin",
					TopColor:    "00A6A6A6",
					Bottom:      "thin",
					BottomColor: "00A6A6A6",
				}
				//对齐方式
				alignment := xlsx.Alignment{
					Horizontal: "center",
					Vertical:   "center",
					WrapText:   true,
				}
				//增加标题
				row = sheet.AddRow()
				row.SetHeight(30)
				var names []string
				var fields []string
				var widths []float64
				names = config.ExportConfig.Names
				fields = config.ExportConfig.Fields
				widths = config.ExportConfig.Widths
				style1 := &xlsx.Style{
					Fill:      *xlsx.NewFill("solid", "00DDD9C4", "00DDD9C4"),
					Border:    border,
					Alignment: alignment,
				}
				for k, name := range names {
					cell = row.AddCell()
					cell.SetString(name)
					cell.SetStyle(style1)
					if k < len(widths) {
						sheet.Col(k).Width = widths[k]
					}
				}
				//增加其他
				style2 := &xlsx.Style{
					Border:    border,
					Alignment: alignment,
				}
				for _, v := range *data {
					row = sheet.AddRow()
					row.SetHeight(50)
					for _, field := range fields {
						cell = row.AddCell()
						if strings.Contains(field, ".") {
							tmp := strings.Split(field, ".")
							if len(tmp) == 2 {
								//log.Println("tmp[0]:", tmp[0], "  tmp[1]:", tmp[1])
								if v[tmp[0]] != nil {
									fieldObject := v[tmp[0]].(map[string]interface{})
									if tmp[0] == "CVUS" {
										cell.SetValue("-")
										for kk, _ := range fieldObject {
											if strings.Index(kk, "bankuai_") > -1 {
												cell.SetValue("斑块")
												break
											} else if fieldObject[tmp[1]] == "全部正常" {
												cell.SetValue("全部正常")
												break
											}
										}

									} else {
										cell.SetValue(fieldObject[tmp[1]])
									}
								} else {
									if tmp[0] == "CVUS" {
										cell.SetValue("-")
									} else {
										cell.SetValue("")
									}

								}

							}
						} else {
							fieldValue := v[field]
							if fieldValue != nil {
								if field == "area" {
									cell.SetValue(getAreaNameByCode(fieldValue.(string)))
								} else if field == "createTime" {
									if fieldValue != "" {
										cell.SetValue(date.FormatYYYYMMDD(time.Unix(fieldValue.(int64), 0)))
									} else {
										cell.SetValue("")
									}

								} else {
									cell.SetValue(fieldValue.(string))
								}
							} else {
								cell.SetValue("")
							}
						}
						cell.SetStyle(style2)
					}
				}
				now := time.Now()
				fileName = fileName + "_筛查数据_" + date.FormatDate(&now, date.Date_Short_Layout)
				ctx.Writer.Header().Set("Content-Disposition", "attachment; filename="+fileName+".xlsx")
				file.Write(ctx.Writer)
			} else {
				msg := ""
				if dataLen > 15000 {
					msg = "<script>alert('查询记录过大,请调整查询条件重新导出');window.location.href='/infoCollection';</script>"
				} else if dataLen == 0 {
					msg = "<script>alert('查询导出的记录不存在,请调整查询条件,或去历史筛查记录中查询导出!');window.location.href='/infoCollection';</script>"
				}
				ctx.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
				ctx.Writer.Write([]byte(msg))
			}
		} else {
			log.Println("数据导出查询参数反序列化失败:", err)
		}
	} else {
		log.Println("数据导出查询参数为空......")
	}
}

func dealPastMedicalHistoryUpdateData(_pastMedicalHistoryData, _physicalCheckup, _labExamination map[string]interface{}, _ccRiskRating map[string]interface{}) {
	if _pastMedicalHistoryData["gaoxueya"].(string) == "有" || checkGaoXueYaFromPhysicalCheckup(_physicalCheckup) {
		log.Printf("有高血压,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_gaoxueya"] = "有"
		log.Printf("_ccRiskRating['fengxianpingji_gaoxueya']设置[有]成功......")
	} else {
		_ccRiskRating["fengxianpingji_gaoxueya"] = "无"
	}

	if _pastMedicalHistoryData["xzyc"].(string) == "有" || checkXueZhiFromLabExamination(_labExamination) {
		log.Printf("有血脂异常,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_xzyc"] = "是"
		log.Printf("_ccRiskRating['fengxianpingji_xzyc']设置[是]成功......")
	} else {
		_ccRiskRating["fengxianpingji_xzyc"] = "否"
	}
	if _pastMedicalHistoryData["tnb"].(string) == "有" || checkTNBFromLabExamination(_labExamination) {
		log.Printf("有糖尿病,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_tnb"] = "有"
		log.Printf("_ccRiskRating['fengxianpingji_tnb']设置[有]成功......")
	} else {
		_ccRiskRating["fengxianpingji_tnb"] = "无"
	}

	if _pastMedicalHistoryData["xinzangbing"].(string) == "有" && strings.Index(_pastMedicalHistoryData["xinzangbing_leixing"].(string), "房颤") > -1 {
		log.Printf("有心脏病类型是房颤,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_fc"] = "有"
		log.Printf("_ccRiskRating['fengxianpingji_fc']设置[有]成功......")
	} else {
		_ccRiskRating["fengxianpingji_fc"] = "无"
	}
	if _pastMedicalHistoryData["naocuzhong"].(string) == "有" {
		log.Printf("有既往脑卒中,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_naocuzhong_history"] = "有"
		log.Printf("_ccRiskRating['fengxianpingji_naocuzhong_history']设置[有]成功......")
	} else {
		_ccRiskRating["fengxianpingji_naocuzhong_history"] = "无"
	}
	if _pastMedicalHistoryData["naoquexue"].(string) == "有" {
		log.Printf("有既往TIA,设置ccRiskRating")
		_ccRiskRating["fengxianpingji_TIA_history"] = "有"
		log.Printf("_ccRiskRating['fengxianpingji_TIA_history']设置[有]成功......")
	} else {
		_ccRiskRating["fengxianpingji_TIA_history"] = "无"
	}

}

func checkGaoXueYaFromPhysicalCheckup(_m map[string]interface{}) bool {
	var (
		firstSBP, firstDSP, secondSBP, secondDSP int
		b                                        bool
	)
	if _m["tigejiancha_xueya_firstSBP"] != nil {
		firstSBP, _ = strconv.Atoi(_m["tigejiancha_xueya_firstSBP"].(string))
	}
	if _m["tigejiancha_xueya_firstDSP"] != nil {
		firstDSP, _ = strconv.Atoi(_m["tigejiancha_xueya_firstDSP"].(string))
	}

	if _m["tigejiancha_xueya_secondSBP"] != nil {
		secondSBP, _ = strconv.Atoi(_m["tigejiancha_xueya_secondSBP"].(string))
	}
	if _m["tigejiancha_xueya_secondDSP"] != nil {
		secondDSP, _ = strconv.Atoi(_m["tigejiancha_xueya_secondDSP"].(string))
	}
	if firstSBP >= 140 || secondSBP >= 140 || firstDSP >= 90 || secondDSP >= 90 {
		b = true
	} else {
		b = false
	}
	return b
}

func checkXueZhiFromLabExamination(_m map[string]interface{}) bool {
	var b bool
	//实验室检查
	var (
		xuezhi_ganyousanzhi, xuezhi_danguchun, xuezhi_gaomidu float64
	)
	if _m["xuezhi_ganyousanzhi"] != nil {
		xuezhi_ganyousanzhi, _ = strconv.ParseFloat(_m["xuezhi_ganyousanzhi"].(string), 64)
	}
	if _m["xuezhi_danguchun"] != nil {
		xuezhi_danguchun, _ = strconv.ParseFloat(_m["xuezhi_danguchun"].(string), 64)
	}
	if _m["xuezhi_gaomidu"] != nil {
		xuezhi_gaomidu, _ = strconv.ParseFloat(_m["xuezhi_gaomidu"].(string), 64)
	}
	if xuezhi_danguchun >= 6.22 || xuezhi_ganyousanzhi >= 2.26 || (xuezhi_gaomidu < 1.04 && xuezhi_gaomidu > 0) {
		b = true
	} else {
		b = false
	}
	return b
}

func checkTNBFromLabExamination(_m map[string]interface{}) bool {
	var b bool
	//实验室检查
	var (
		xuetang_kongfu, xuetang_canhou float64
	)
	if _m["xuetang_kongfu"] != nil {
		xuetang_kongfu, _ = strconv.ParseFloat(_m["xuetang_kongfu"].(string), 64)
	}
	if _m["xuetang_canhou"] != nil {
		xuetang_canhou, _ = strconv.ParseFloat(_m["xuetang_canhou"].(string), 64)
	}
	if xuetang_kongfu >= 7.0 || xuetang_canhou >= 11.0 {
		b = true
	} else {
		b = false
	}
	return b
}

func getAreaNameByCode(areaCode string) string {
	str := strings.Split(areaCode, "-")
	if len(str) == 2 {
		parentCode := str[0]
		for _, val := range config.Organs {
			str := val["organCode"].(string)
			if str == parentCode {
				for _, child := range val["children"].([]interface{}) {
					if child != nil {
						tmp := child.(map[string]interface{})
						if tmp["organCode"] == areaCode {
							return tmp["organName"].(string)
						}
					}

				}
			}
		}
	} else {
		for _, val := range config.Organs {
			str := val["organCode"].(string)
			if str == areaCode {
				return val["organName"].(string)
			}
		}
	}

	return ""
}
func GetSessionInfo(key string, ctx *gin.Context) interface{} {
	session := sessions.Default(ctx)
	return session.Get(key)
}
